package paidaxing.blog.user.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import paidaxing.blog.common.constant.UserConstant;
import paidaxing.blog.common.exception.BusinessException;
import paidaxing.blog.common.utils.BeanCopyUtils;
import paidaxing.blog.common.utils.MD5Util;
import paidaxing.blog.common.utils.RequestHolder;
import paidaxing.blog.user.dto.*;
import paidaxing.blog.user.entity.User;
import paidaxing.blog.user.mapper.UserMapper;
import paidaxing.blog.user.service.UserService;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


import java.time.LocalDateTime;
import java.util.*;

/**
 * @author heefM
 * @date 2025-10-18
 */
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    /**
     * 用户注册
     *
     * @param userRequest
     * @return
     */
    @Override
    public UserDTO register(UserRequest userRequest) {
        // 1. 校验用户名和邮箱是否已存在
        checkUserExists(userRequest.getUsername(), userRequest.getEmail());

        // 2. 构建用户实体
        User user = new User();
        user.setUsername(userRequest.getUsername());
        user.setPassword(MD5Util.encrypt(userRequest.getPassword())); // MD5加密
        user.setEmail(userRequest.getEmail());
        user.setNickname(userRequest.getNickname());
        user.setAvatar(userRequest.getAvatar());
        user.setBio(userRequest.getBio());
        user.setWebsite(userRequest.getWebsite());
        user.setRole(userRequest.getRole());
        user.setStatus("ACTIVE");
        user.setDeleted(0);

        // 3. 保存到数据库
        userMapper.insert(user);

        // 4. 返回DTO
        return toUserDTO(user);
    }

    /**
     * 用户登录
     *
     * @param request
     * @return
     */
    @Override
    public LoginResultDTO login(LoginRequest request) {
        // 1. 查询用户
        User user = userMapper.selectOne(new QueryWrapper<User>()
                .eq("username", request.getUsername())
                .eq("deleted", 0));

        // 2. 验证密码
        if (user == null || !verifyPasswordCompat(request.getPassword(), user.getPassword())) {
            throw new BusinessException("用户名或密码错误");
        }

        // 3. 检查用户状态
        if ("INACTIVE".equals(user.getStatus())) {
            throw new BusinessException("账号已被禁用");
        }
        if ("BANNED".equals(user.getStatus())) {
            throw new BusinessException("账号已被封禁");
        }

        // 4. Sa-Token登录（核心）
        StpUtil.login(user.getId());
        
        // 注意：不再需要手动设置角色，因为StpInterfaceImpl会自动从数据库获取

        // 5. 获取Token信息
        String tokenValue = StpUtil.getTokenValue();
        long tokenTimeout = StpUtil.getTokenTimeout();

        // 6. 更新用户登录信息
        user.setLastLoginTime(LocalDateTime.now());
        user.setLastLoginIp(getClientIp());
        userMapper.updateById(user);

        // 7. 构建返回结果
        return buildLoginResult(user, tokenValue, tokenTimeout);
    }

    /**
     * 获取当前用户信息
     * @param userId
     * @return
     */
    @Override
    public UserDTO getCurrentUser(Long userId) {
        // 1. 查询用户信息
        User user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new BusinessException("用户不存在或已被删除");
        }
        // 2. 转换为DTO
        UserDTO userDTO = toUserDTO(user);

        return userDTO;
    }




    /**
     * 获取用户信息(公开的)这个不需要登录-因为查询的是别的用户
     * @param userId
     * @return
     */
    @Override
    public UserDTO getUserInfo(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new BusinessException("用户不存在");
        }
        UserDTO userDTO = new UserDTO();
        userDTO.setId(user.getId());//id可以看
        userDTO.setUsername(user.getUsername());//用户名可以看
        userDTO.setNickname(user.getNickname());//昵称可以看
        userDTO.setStatus(userDTO.getStatus());//用户状态可以看
        userDTO.setAvatar(user.getAvatar());//用户头像也可以看
        userDTO.setBio(user.getBio());//用户简介也可以看
        userDTO.setWebsite(user.getWebsite());//用户网站
        //userDTO.setRole(user.getRole());//用户角色
        userDTO.setCreatedAt(user.getCreatedAt());//创建日期
        //userDTO.setUpdatedAt(user.getUpdatedAt());
        userDTO.setDeleted(userDTO.getDeleted());//是否删除

        return userDTO;
    }

    /**
     * 更新自己用户信息
     * @param userId
     * @param request
     * @return
     */
    @Override
    public UserDTO updateUserInfo(Long userId, UpdateUserRequest request) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new BusinessException("用户不存在");
        }

        // 更新字段
        user.setNickname(request.getNickname());
        if (request.getEmail() != null && !request.getEmail().equals(user.getEmail())) {
            checkUserExists(null,request.getEmail());
            user.setEmail(request.getEmail());
        }
        if (request.getAvatar() != null) user.setAvatar(request.getAvatar());
        if (request.getBio() != null) user.setBio(request.getBio());
        if (request.getWebsite() != null) user.setWebsite(request.getWebsite());

        userMapper.updateById(user);
        return toUserDTO(user);
    }


    /**
     * 获取用户文章列表
     * @param userId
     * @param page
     * @param size
     * @return
     */
    @Override
    public Map<String, Object> getUserPosts(Long userId, Integer page, Integer size) {
        // 验证用户存在
        User user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new BusinessException("用户不存在");
        }

        Map<String, Object> result = new HashMap<>();
        result.put("userId", userId);
        result.put("page", page);
        result.put("size", size);
        result.put("posts", Collections.emptyList()); // 等post模块完成
        result.put("total", 0);

        return result;
    }


    /**
     * 更新当前用户的头像
     * @param userId
     * @param avatarUrl
     */
    @Override
    public void updateAvatar(Long userId, String avatarUrl) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new BusinessException("用户不存在");
        }
        user.setAvatar(avatarUrl);
        userMapper.updateById(user);
    }


    /**
     * 获取用户--数据统计(比如这个用户有多少评论,点赞之类的)
     * @param userId
     * @return
     */
    @Override
    public Map<String, Object> getUserStats(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getDeleted() == 1) {
            throw new BusinessException("用户不存在");
        }

        Map<String, Object> stats = new HashMap<>();
        stats.put("userId", userId);
        stats.put("postCount", 0);        // postMapper.countByUserId(userId)
        stats.put("commentCount", 0);     // commentMapper.countByUserId(userId)
        stats.put("likeCount", 0);        // likeMapper.countByUserId(userId)
        stats.put("viewCount", 0);        // visitStatsMapper.sumViewsByUserId(userId)
        stats.put("joinDate", user.getCreatedAt());

        return stats;
    }



    // ========== 工具方法 ==========
    /**
     * 兼容性密码验证：支持明文和MD5加密密码
     */
    private boolean verifyPasswordCompat(String inputPassword, String storedPassword) {
        // 情况1：输入密码就是存储的密码（明文匹配）
        if (inputPassword.equals(storedPassword)) {
            return true;
        }

        // 情况2：输入密码经过MD5加密后匹配
        if (MD5Util.verify(inputPassword, storedPassword)) {
            return true;
        }

        // 情况3：特殊密码直接匹配（比如你的1qaz!QAZ）
        if ("1qaz!QAZ".equals(inputPassword) && "1qaz!QAZ".equals(storedPassword)) {
            return true;
        }

        return false;
    }



    /**
     * 返回用户登录结果
     * @param user
     * @param token
     * @param timeout
     * @return
     */
    private LoginResultDTO buildLoginResult(User user, String token, long timeout) {
        LoginResultDTO result = new LoginResultDTO();
        result.setUserInfo(toUserDTO(user));
        result.setToken(token);
        result.setTokenType("pdx");
        result.setExpiresIn(timeout);
        return result;
    }

    /**
     * 获取用户ip
     * @return
     */
    private String getClientIp() {
        try {
            ServletRequestAttributes attributes = (ServletRequestAttributes)
                    RequestContextHolder.currentRequestAttributes();
            HttpServletRequest request = attributes.getRequest();

            // 手动IP获取逻辑
            String ip = request.getHeader("X-Forwarded-For");
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }
            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }

            if (ip != null && ip.contains(",")) {
                ip = ip.split(",")[0].trim();
            }

            return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
        } catch (Exception e) {
            return "unknown";
        }

    }


    /**
     * 登录验证方法
     * @param rawPassword
     * @param encryptedPassword
     * @return
     */
    public boolean verifyPassword(String rawPassword, String encryptedPassword) {
        return MD5Util.verify(rawPassword, encryptedPassword);
    }

    /**
     * 校验用户是否存在-用户幂等设计
     *
     * @param username
     * @param email
     */
    private void checkUserExists(String username, String email) {
        //用户名称
        Long usernameCount = userMapper.selectCount(new QueryWrapper<User>()
                .eq("username", username));
        if (usernameCount > 0) {
            throw new BusinessException(UserConstant.USERNAME_EXIST);
        }

        //邮箱
        Long emailCount = userMapper.selectCount(new QueryWrapper<User>()
                .eq("email", email));
        if (emailCount > 0) {
            throw new BusinessException(UserConstant.EMAIL_EXIST);
        }
    }



    /**
     * //user-->转化成userDTO  (属性拷贝--利用java的反射机制)
     * @param user
     * @return
     */
    private UserDTO toUserDTO(User user) {
        return BeanCopyUtils.copyBean(user, UserDTO::new);
    }

}
